﻿@page "/Account/Login"
@rendermode InteractiveServer
@attribute [ReuseTabsPage(Ignore = true)]

@layout SageKing.Blazor.OpenIdService.Components.Layout.LoginLayout

@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity
@using SageKing.Blazor.OpenIdService.Services
@using SageKing.OpenIddict.UI.Infrastructure.Data


@inject ILogger<Login> Logger
@inject NavigationManager NavigationManager

<PageTitle>Log in</PageTitle>

<h1>Log in</h1>
<div class="row">
	<div class="col-md-4">
		<section>
			<StatusMessage Message="@errorMessage" />
			<EditForm Model="Input" method="post" OnValidSubmit="LoginUser" FormName="login">
				<DataAnnotationsValidator />
				<h2>Use a local account to log in.</h2>
				<hr />
				<ValidationSummary class="text-danger" role="alert" />
				<div class="form-floating mb-3">
					<InputText @bind-Value="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
					<label for="email" class="form-label">Email</label>
					<ValidationMessage For="() => Input.Email" class="text-danger" />
				</div>
				<div class="form-floating mb-3">
					<InputText type="password" @bind-Value="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" placeholder="password" />
					<label for="password" class="form-label">Password</label>
					<ValidationMessage For="() => Input.Password" class="text-danger" />
				</div>
				<div class="checkbox mb-3">
					<label class="form-label">
						<InputCheckbox @bind-Value="Input.RememberMe" class="darker-border-checkbox form-check-input" />
						Remember me
					</label>
				</div>
				<div>
					<button type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
				</div>
				<div>
					<p>
						<a href="Account/ForgotPassword">Forgot your password?</a>
					</p>
					<p>
						<a href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))">Register as a new user</a>
					</p>
					<p>
						<a href="Account/ResendEmailConfirmation">Resend email confirmation</a>
					</p>
				</div>
			</EditForm>
		</section>
	</div>
	<div class="col-md-6 col-md-offset-2">
		<section>
			<h3>Use another service to log in.</h3>
			<hr />
			<ExternalLoginPicker />
		</section>
	</div>
</div>

@code {
	private string? errorMessage;

	[CascadingParameter]
	[Inject] public AuthenticationStateProvider AuthProvider { get; set; }
	public CustomAuthStateProvider AuthStateProvider
	{
		get
		{
			return (CustomAuthStateProvider)AuthProvider;
		}
	}

	[SupplyParameterFromForm]
	private LoginInput Input { get; set; } = new();

	[SupplyParameterFromQuery]
	private string? ReturnUrl { get; set; }

	[CascadingParameter]
	public Error? Error { get; set; }

	protected override async Task OnInitializedAsync()
	{
		if (AuthStateProvider.ServerOption.IsTestingEnvironment)
		{
			demoUser();
		}
	}

	protected override async Task OnAfterRenderAsync(bool firstRender)
	{
		if (firstRender)
		{
			try
			{
				await GetAuthenticationStateAsync();
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
			}
		}
	}
	public async Task GetAuthenticationStateAsync()
	{
		try
		{
			var state = await AuthStateProvider.GetAuthenticationStateAsync();
			if (state.User.IsAuthenticated())
			{
				Logger.LogInformation("[IsAuthenticated] User logged in.");
				var tmpURL = ReturnUrl.StartsWithCheck("/");
				NavigationManager.NavigateTo(tmpURL);
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex);
		}

	}


	void demoUser()
	{
		Input.Email = "admin@openiddict.com";
		Input.Password = "Pass123$";
	}

	public async Task LoginUser()
	{
		try
		{
			// This doesn't count login failures towards account lockout
			// To enable password failures to trigger account lockout, set lockoutOnFailure: true

			//判断是否管理员
			var tmpCustomProvider = ((CustomAuthStateProvider)AuthProvider);
			var resultAll = await tmpCustomProvider.AuthService.SignIn(Input);
			var result = resultAll.Item1;

			if (result.Succeeded)
			{
				Logger.LogInformation("User logged in.");
				var tmpURL = ReturnUrl.StartsWithCheck("/");
				NavigationManager.NavigateTo(tmpURL);
				return;
			}
			else if (result.RequiresTwoFactor)
			{
				NavigationManager.NavigateTo(
					$"/Account/LoginWith2fa?returnUrl={ReturnUrl.UrlEncode()}&rememberMe={Input.RememberMe}");
			}
			else if (result.IsLockedOut)
			{
				Logger.LogWarning("User account locked out.");
				NavigationManager.NavigateTo("/Account/Lockout");
			}
			else
			{
				errorMessage = "Error: Invalid login attempt.";
			}
		}
		catch (Exception ex)
		{
			Error?.ProcessError(ex);
		}
	}
}
